/*
 * BoardManagerPanel.java
 *
 * Created on den 26 november 2006
 */

package quizgame.admin;

import java.util.Arrays;
import javax.swing.AbstractListModel;
import javax.swing.DefaultListModel;
import javax.swing.JOptionPane;
import quizgame.common.Constants;

/**
 *
 * @author rheo
 */
public class BoardManagerPanel extends javax.swing.JPanel {
    public BoardEditorPanel boardEditorPanel;
    public BoardsListModel boardsListModel = new BoardsListModel();
    private AdminConnection adminConnection;
    private String[] boardNames;
    
    /** Creates new form BoardManagerPanel */
    public BoardManagerPanel(AdminConnection adminConnection) {
        this.adminConnection = adminConnection;
        boardEditorPanel = new BoardEditorPanel(adminConnection);
        initComponents();
        boardEditor.add(boardEditorPanel);
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        javax.swing.JPanel jPanel1 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        boardList = new javax.swing.JList();
        editButton = new javax.swing.JButton();
        renameButton = new javax.swing.JButton();
        deleteButton = new javax.swing.JButton();
        setAsCurrentButton = new javax.swing.JButton();
        emptyBoardButton = new javax.swing.JButton();
        boardEditor = new javax.swing.JPanel();

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Boards"));

        boardList.setModel(boardsListModel);
        boardList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                boardListValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(boardList);

        editButton.setText("Edit selected");
        editButton.setEnabled(false);
        editButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editButtonActionPerformed(evt);
            }
        });

        renameButton.setText("Rename selected...");
        renameButton.setEnabled(false);
        renameButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                renameButtonActionPerformed(evt);
            }
        });

        deleteButton.setText("Delete selected...");
        deleteButton.setEnabled(false);
        deleteButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteButtonActionPerformed(evt);
            }
        });

        setAsCurrentButton.setText("Set as current");
        setAsCurrentButton.setEnabled(false);
        setAsCurrentButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                setAsCurrentButtonActionPerformed(evt);
            }
        });

        emptyBoardButton.setText("Set empty board");
        emptyBoardButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                emptyBoardButtonActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 147, Short.MAX_VALUE)
                    .add(emptyBoardButton, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 147, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, editButton, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 147, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, setAsCurrentButton, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 147, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, deleteButton, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 147, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, renameButton, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 147, Short.MAX_VALUE))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
                .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 203, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(editButton)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(renameButton)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(deleteButton)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(setAsCurrentButton)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(emptyBoardButton)
                .add(11, 11, 11))
        );

        boardEditor.setLayout(new javax.swing.BoxLayout(boardEditor, javax.swing.BoxLayout.LINE_AXIS));

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(boardEditor, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 456, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, boardEditor, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 386, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    private void setAsCurrentButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_setAsCurrentButtonActionPerformed
        if(JOptionPane.showConfirmDialog(this, "Reset the current game?", Constants.applicationName, JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
            adminConnection.setBoard((String) boardList.getSelectedValue());
        }
    }//GEN-LAST:event_setAsCurrentButtonActionPerformed

    private void boardListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_boardListValueChanged
        int count = boardList.getSelectedValues().length;
        
        editButton.setEnabled(count == 1);
        renameButton.setEnabled(count == 1);
        deleteButton.setEnabled(count > 0);
        setAsCurrentButton.setEnabled(count == 1);
    }//GEN-LAST:event_boardListValueChanged

    private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed
        if(JOptionPane.showConfirmDialog(this, "Delete the selected boards? This cannot be undone.", Constants.applicationName, JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
            int[] selectedIndices = boardList.getSelectedIndices();
            String[] boardNames = new String[selectedIndices.length];
            
            for(int i = 0; i < selectedIndices.length; i++) {
                boardNames[i] = (String) boardsListModel.getElementAt(selectedIndices[i]);
            }
            
            adminConnection.removeBoards(boardNames);
        }
    }//GEN-LAST:event_deleteButtonActionPerformed

    private void renameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_renameButtonActionPerformed
        String newName = JOptionPane.showInputDialog(this, "New name", boardList.getSelectedValue());
        if(newName != null) {
            adminConnection.setBoardName((String) boardList.getSelectedValue(), newName);
        }
    }//GEN-LAST:event_renameButtonActionPerformed

    private void editButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editButtonActionPerformed
        if(boardEditorPanel.boardTreeModel.categories.length <= 0 || JOptionPane.showConfirmDialog(this, "Discard the current board?", null, JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
            adminConnection.getBoard((String) boardList.getSelectedValue());
        }
    }//GEN-LAST:event_editButtonActionPerformed

    private void emptyBoardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_emptyBoardButtonActionPerformed
        if(JOptionPane.showConfirmDialog(this, "Reset the current game and remove current board?", Constants.applicationName, JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
            adminConnection.setActiveBoard(null);
        }
    }//GEN-LAST:event_emptyBoardButtonActionPerformed
    
    public class BoardsListModel extends AbstractListModel {
        String[] boardNames = new String[0];
        
        public int getSize() {
            return boardNames.length;
        }

        public Object getElementAt(int index) {
            return boardNames[index];
        }
        
        public void setBoardList(String[] names) {
            fireIntervalRemoved(this, 0, boardNames.length);
            Arrays.sort(names);
            boardNames = names;
            fireIntervalAdded(this, 0, boardNames.length - 1);
        }
        
        public void removeBoards(int[] indices) {
            int count = 0;
            String[] oldBoardNames = boardNames;
            
            for(int index : indices) {
                if(boardNames[index] != null) {
                    boardNames[index] = null;
                    count++;
                }
            }
            
            boardNames = new String[boardNames.length - count];
            count = 0;
            
            for(String boardName : oldBoardNames) {
                if(boardName != null) {
                    boardNames[count] = boardName;
                    count++;
                }
            }
            
            fireIntervalRemoved(this, 0, oldBoardNames.length);
        }
        
        public void setBoardName(int oldIndex, String newName) {
            int newIndex = -Arrays.binarySearch(boardNames, newName) - 1;
            
            if(newIndex > oldIndex) {
                newIndex--;
                System.arraycopy(boardNames, oldIndex + 1, boardNames, oldIndex, newIndex - oldIndex);
            } else if(newIndex < oldIndex) {
                System.arraycopy(boardNames, newIndex, boardNames, newIndex + 1, oldIndex - newIndex);
            }
            
            boardNames[newIndex] = newName;
            
            if(newIndex == oldIndex) {
                fireContentsChanged(this, newIndex, newIndex);
            } else {
                fireIntervalRemoved(this, oldIndex, oldIndex);
                fireIntervalAdded(this, newIndex, newIndex);
            }
        }
        
        public void addBoard(String name) {
            int index = -Arrays.binarySearch(boardNames, name) - 1;
            boardNames = SortedArrays.add(boardNames, new String[boardNames.length + 1], index, name);
            fireIntervalAdded(this, index, index);
        }
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel boardEditor;
    private javax.swing.JList boardList;
    private javax.swing.JButton deleteButton;
    private javax.swing.JButton editButton;
    private javax.swing.JButton emptyBoardButton;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JButton renameButton;
    private javax.swing.JButton setAsCurrentButton;
    // End of variables declaration//GEN-END:variables
    
}
